package com.codeboy.qianghongbao.util;

import android.accessibilityservice.AccessibilityService;
import android.os.Build;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityNodeInfo;

import java.lang.reflect.Field;
import java.util.List;

/**
 * <p>Created 16/2/4 上午9:49.</p>
 * <p><a href="mailto:730395591@qq.com">Email:730395591@qq.com</a></p>
 * <p><a href="http://www.happycodeboy.com">LeonLee Blog</a></p>
 * 工具类
 *
 * @author LeonLee
 */
public final class AccessibilityHelper {


    /**
     * 私有化构造函数
     */
    private AccessibilityHelper() {
    }

    /**
     * 查找节点对象.
     * <p>
     * 通过给定父节点对象和指定的子节点资源ID,获取指定的子节点对象
     *
     * @param rootNode 欲查找的根节点对象
     * @param resId    欲查找的子节点的资源ID
     * @return 查找成功返回指定的节点, 获取返回null
     */
    public static AccessibilityNodeInfo findNodeInfoById(AccessibilityNodeInfo rootNode, String resId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            // 获取到所有的子节点对象
            List<AccessibilityNodeInfo> list = rootNode.findAccessibilityNodeInfosByViewId(resId);
            if (list != null && !list.isEmpty()) {
                return list.get(0);
            }
        }
        return null;
    }

    /**
     * 通过文本查找
     */
    public static AccessibilityNodeInfo findNodeInfosByText(AccessibilityNodeInfo rootNode, String text) {
        List<AccessibilityNodeInfo> list = rootNode.findAccessibilityNodeInfosByText(text);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 通过关键字查找
     */
    public static AccessibilityNodeInfo findNodeInfosByTexts(AccessibilityNodeInfo rootNode, String... texts) {
        for (String key : texts) {
            AccessibilityNodeInfo info = findNodeInfosByText(rootNode, key);
            if (info != null) {
                return info;
            }
        }
        return null;
    }

    /**
     * 通过组件名字查找
     */
    public static AccessibilityNodeInfo findNodeInfosByClassName(AccessibilityNodeInfo rootNode, String className) {
        if (TextUtils.isEmpty(className)) {
            return null;
        }
        for (int i = 0; i < rootNode.getChildCount(); i++) {
            AccessibilityNodeInfo node = rootNode.getChild(i);
            if (className.equals(node.getClassName())) {
                return node;
            }
        }
        return null;
    }

    /**
     * 找父组件
     */
    public static AccessibilityNodeInfo findParentNodeInfosByClassName(AccessibilityNodeInfo rootNode, String className) {
        if (rootNode == null) {
            return null;
        }
        if (TextUtils.isEmpty(className)) {
            return null;
        }
        if (className.equals(rootNode.getClassName())) {
            return rootNode;
        }
        return findParentNodeInfosByClassName(rootNode.getParent(), className);
    }

    private static final Field sSourceNodeField;

    static {
        Field field = null;
        try {
            field = AccessibilityNodeInfo.class.getDeclaredField("mSourceNodeId");
            field.setAccessible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        sSourceNodeField = field;
    }

    public static long getSourceNodeId(AccessibilityNodeInfo nodeInfo) {
        if (sSourceNodeField == null) {
            return -1;
        }
        try {
            return sSourceNodeField.getLong(nodeInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    public static String getViewIdResourceName(AccessibilityNodeInfo nodeInfo) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            return nodeInfo.getViewIdResourceName();
        }
        return null;
    }

    /**
     * 返回主界面事件
     */
    public static void performHome(AccessibilityService service) {
        if (service == null) {
            return;
        }
        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
    }

    /**
     *
     */
    /**
     * 返回事件
     *
     * @param service 辅助服务对象
     */
    public static void performBack(AccessibilityService service) {
        if (service == null) {
            return;
        }
        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
    }

    /**
     * 点击事件
     */
    public static void performClick(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo == null) {
            return;
        }
        if (nodeInfo.isClickable()) {
            nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        } else {
            performClick(nodeInfo.getParent());
        }
    }
}
